package com.dy.yunying.biz.service.usergroup.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dy.yunying.api.entity.usergroup.UserGroup;
import com.dy.yunying.api.entity.usergroup.UserGroupLog;
import com.dy.yunying.api.enums.DimensionEnum;
import com.dy.yunying.api.enums.GroupClassEnum;
import com.dy.yunying.api.enums.UserGroupBindInfoQryTypeEnum;
import com.dy.yunying.api.enums.UserGroupTypeEnum;
import com.dy.yunying.api.req.usergroup.UserGroupStatReq;
import com.dy.yunying.api.vo.usergroup.UserGroupNoticePriceVO;
import com.dy.yunying.api.vo.usergroup.UserGroupStatVO;
import com.dy.yunying.api.vo.usergroup.UserGroupVo;
import com.dy.yunying.biz.config.YunYingProperties;
import com.dy.yunying.biz.dao.ads.hongbao.PopupNoticeMapper;
import com.dy.yunying.biz.dao.ads.prize.PrizePushMapper;
import com.dy.yunying.biz.dao.ads.usergroup.UserGroupLogMapper;
import com.dy.yunying.biz.dao.ads.usergroup.UserGroupMapper;
import com.dy.yunying.biz.service.usergroup.UserGroupService;
import com.pig4cloud.pig.api.util.StringUtils;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.util.*;

@Log4j2
@Service("userGroupService")
@RequiredArgsConstructor
public class UserGroupServiceImpl extends ServiceImpl<UserGroupMapper, UserGroup> implements UserGroupService {

	private final UserGroupMapper userGroupMapper;

	private final UserGroupLogMapper userGroupLogMapper;

	private final PopupNoticeMapper popupNoticeMapper;
	private final PrizePushMapper prizePushMapper;
	private final YunYingProperties yunYingProperties;

	@Override
	@Transactional(value = "adsTransactionManager", rollbackFor = Exception.class)
	public R saveOrUpdateUserGroup(UserGroupVo vo) throws Throwable{
		UserGroup entity = new UserGroup();
		try {
			String msg = checkVo(vo);
			if(StringUtils.isNotBlank(msg)){
				return R.failed(msg);
			}

			//1.新增，2.修改 3.删除
			Integer type = null;
			BeanUtils.copyProperties(vo, entity);
			if(Objects.nonNull(entity.getId())){
				//更新
				userGroupMapper.updateById(entity);
				type = 2;
			}else{
				entity.setCreateId(SecurityUtils.getUser().getId().longValue());
				entity.setDxAppId(yunYingProperties.getDongxinAppid());
				userGroupMapper.insert(entity);
				type = 1;
			}
			UserGroupLog log = new UserGroupLog();
			log.setCreateId(SecurityUtils.getUser().getId().longValue());
			log.setType(type);
			log.setGroupId(entity.getId());
			log.setContent(JSON.toJSONString(entity));
			userGroupLogMapper.insert(log);
		} catch (Throwable t) {
			log.error("新增/更新用户群组失败", t);
			throw new Throwable(t);
		}
		return R.ok(entity);
	}


	@Override
	public boolean updateByGroupId(UserGroup userGroup) {
		return userGroupMapper.updateById(userGroup) == 1?true:false;
	}

	@Override
	public List<UserGroupStatVO> getStatNums(@Valid UserGroupStatReq req) {
		List<UserGroupStatVO> resultList = new ArrayList<>();
		List<UserGroupStatVO> noticeList;
		List<UserGroupStatVO> prizeList;

		UserGroupBindInfoQryTypeEnum qryTypeEnum = UserGroupBindInfoQryTypeEnum.getOneByType(req.getQryType());
		switch (qryTypeEnum){
			case NOTICE_AND_PRIZE:
				// 查询公告数
				noticeList = popupNoticeMapper.countWithUserGroupIds(req.getGroupIds());

				// 查询奖励数
				prizeList = prizePushMapper.countWithUserGroupIds(req.getGroupIds());

				// 处理返回结果
				for (Long item : req.getGroupIds()) {
					resultList.add(new UserGroupStatVO(item));
				}
				resultList.forEach(a->{
					noticeList.stream().filter(b -> a.getGroupId().equals(b.getGroupId())).forEach(b -> {
						a.setNoticeNums(b.getNums());
					});
					prizeList.stream().filter(b -> a.getGroupId().equals(b.getGroupId())).forEach(b -> {
						a.setPrizeNums(b.getNums());
					});
				});

				return resultList;
			case NOTICE:
				// 查询公告数
				noticeList = popupNoticeMapper.countWithUserGroupIds(req.getGroupIds());
				return noticeList;
			case PRIZE:
				// 查询奖励数
				prizeList = prizePushMapper.countWithUserGroupIds(req.getGroupIds());
				return prizeList;
			case NOTICE_OR_PRIZE:
				// 查询公告数
				noticeList = popupNoticeMapper.countWithUserGroupIds(req.getGroupIds());
				if(CollectionUtils.isNotEmpty(noticeList)){
					return noticeList;
				}
				// 查询奖励数
				prizeList = prizePushMapper.countWithUserGroupIds(req.getGroupIds());
				return prizeList;
			default:
				return new ArrayList<>();
		}
	}

	@Override
	public UserGroupNoticePriceVO getBindNoticeList(Long groupId) {
		// 查询公告IDS
		List<Long> noticeList = popupNoticeMapper.getNoticeIdsWithUserGroupId(groupId);
		// 查询奖励IDS
		List<Long> prizeList = prizePushMapper.getPrizeIdsWithUserGroupId(groupId);

		return new UserGroupNoticePriceVO(groupId,noticeList,prizeList);
	}


	private String checkVo(UserGroupVo vo){
		Date now = new Date();

		UserGroup before = null;

		//校验群组名称是否会重复
		if(Objects.nonNull(vo.getId())){
			before = userGroupMapper.selectById(vo.getId());
			if(before == null){
				return "用户群组不存在";
			}
			//更新
			UserGroup userGroup = userGroupMapper.selectOne(Wrappers.<UserGroup>query().lambda().eq(UserGroup::getGroupName, vo.getGroupName()).ne(UserGroup::getId, vo.getId()).last("LIMIT 1"));
			if(userGroup != null){
				return "群组名称存在重复数据";
			}
		}else{
			//新增
			UserGroup userGroup = userGroupMapper.selectOne(Wrappers.<UserGroup>query().lambda().eq(UserGroup::getGroupName, vo.getGroupName()).last("LIMIT 1"));
			if(userGroup != null){
				return "群组名称存在重复数据";
			}
		}

		Integer groupClass = vo.getGroupClass();

		if(groupClass == null){
			return "群组分类不能为空";
		}
		Long classGameid = vo.getClassGameid();
		switch (GroupClassEnum.getOneByType(groupClass)){
			case ALL_GAME:
			case PART_GAME:
				vo.setClassGameid(null);
				break;
			case APPOINT_GAME:
				//指定游戏时，指定游戏id不能为空
				if(classGameid == null){
					return "指定游戏不能为空";
				}
				break;
			default:
				return "群组分类错误";
		}
		//筛选方式
		Integer type = vo.getType();
		if(type == null){
			return "筛选方式不能为空";
		}



		//筛选维度
		Integer dimension = vo.getDimension();
		if(dimension == null){
			return "筛选维度不能为空";
		}
		Long pgameId = vo.getPgameId();
		Long areaId = vo.getAreaId();
		switch (DimensionEnum.getOneByType(dimension)){
			case ACCOUNT:
				vo.setPgameId(null);
				vo.setAreaId(null);
				break;
			case ROLEID:
				//校验游戏归属和区服归属是否为空,这里如果是规则，则不需要归属游戏
				if(pgameId == null && (type != null && UserGroupTypeEnum.ID_FILTER.getType() == type)){
					return "游戏归属不能为空";
				}
				break;
			default:
				return "筛选维度错误";
		}

		//用户归属
		String attribution = vo.getAttribution();
		//用户行为
		String behavior = vo.getBehavior();
		//更新方式：1自动更新，2不更新
		Integer updateMode = vo.getUpdateMode();

		switch (UserGroupTypeEnum.getOneByType(type)){
			//规则
			case RULE:
				//用户归属和用户行为不能为空
				if(StringUtils.isBlank(attribution)){
					return "用户归属不能为空";
				}
				try{
					Map<String, Object> attrMap = JSONObject.parseObject(attribution, new TypeReference<Map<String, Object>>(){});
					Object properties = attrMap.get("properties");
					if(properties == null){
						return "请添加用户归属";
					}
					JSONArray attrArr = JSONArray.parseArray(JSON.toJSONString(properties));
					if(attrArr == null || attrArr.size() == 0){
						return "请添加用户归属";
					}
					for (int i=0; i<attrArr.size(); i++){
						JSONObject item = attrArr.getJSONObject(i);
						String name = item.getString("name");
						if(StringUtils.isBlank(name)){
							return "请选择用户归属选项";
						}
					}

				} catch(Throwable t){
					log.error("解析用户归属失败");
					return "用户归属填写错误";
				}

				if(StringUtils.isBlank(behavior)){
					return "用户行为不能为空";
				}
				try{
					Map<String, Object> behaviorMap = JSONObject.parseObject(behavior, new TypeReference<Map<String, Object>>(){});
					Object properties = behaviorMap.get("properties");
					if(properties == null){
						return "请添加用户行为";
					}
					JSONArray attrArr = JSONArray.parseArray(JSON.toJSONString(properties));
					if(attrArr == null || attrArr.size() == 0){
						return "请添加用户行为";
					}
					for (int i=0; i<attrArr.size(); i++){
						JSONObject item = attrArr.getJSONObject(i);
						String startTime = item.getString("startTime");
						String endTime = item.getString("endTime");
						String whether = item.getString("whether");
						String attributionVo = item.getString("attribution");

						if(StringUtils.isAnyBlank(startTime, endTime, whether, attributionVo)){
							return "请选择用户行为必选项";
						}
					}

				} catch(Throwable t){
					log.error("解析用户行为失败");
					return "用户行为填写错误";
				}


				if(updateMode == null){
					return "更新方式不能为空";
				}
				//新增或者修改了用户归属、用户行为才需要更新
				if(before == null || !attribution.equals(before.getAttribution()) || !behavior.equals(before.getBehavior())){
					vo.setUpdateMark(1);//新标识 0 不需要更新  1需要更新
					vo.setLastUpdateTime(now);
				}
				vo.setPgameId(null);
				vo.setAreaId(null);
				break;
			case ID_FILTER:
				//ID筛选更新方式置空
				vo.setUpdateMode(null);
				break;
			default:
				return "筛选方式错误";
		}
		//添加方式的校验

		return "";
	}

}
